<template>
    <div class="white-box-form">
        <el-form
            ref="ruleRef"
            :model="state.ruleForm"
            :rules="state.rules"
            label-width="120px"
        >
            <!-- 寄件/收货地址 -->
            <div class="flex mb-20">
                <div class="bg-#f7f8fa w-35% pt-10 mr-30">
                    <h2 class="ml-30 mb-10">寄</h2>
                    <el-form-item label="姓名" prop="senderName">
                        <el-input
                            v-model.trim="state.ruleForm.senderName"
                            clearable
                            placeholder="请输入寄件人姓名"
                        />
                    </el-form-item>
                    <el-form-item label="电话" prop="senderPhone">
                        <el-input
                            v-model.trim="state.ruleForm.senderPhone"
                            clearable
                            placeholder="请输入寄件人电话"
                        />
                    </el-form-item>
                    <el-form-item label="地址" prop="senderDistrictCode">
                        <div>
                            <p>{{ state.ruleForm.senderAddress }}</p>
                            <el-button
                                plain
                                type="primary"
                                size="small"
                                @click="onClickChooseAddress(0)"
                                >选择地址</el-button
                            >
                        </div>
                    </el-form-item>
                </div>
                <div class="bg-#f7f8fa w-35% pt-10">
                    <h2 class="ml-30 mb-10 color-red-5">收</h2>
                    <el-form-item label="姓名" prop="receiveName">
                        <el-input
                            v-model.trim="state.ruleForm.receiveName"
                            clearable
                            placeholder="请输入收件人姓名"
                        />
                    </el-form-item>
                    <el-form-item label="电话" prop="receivePhone">
                        <el-input
                            v-model.trim="state.ruleForm.receivePhone"
                            clearable
                            placeholder="请输入收件人电话"
                        />
                    </el-form-item>
                    <el-form-item label="地址" prop="receiveDistrictCode">
                        <div>
                            <p>{{ state.ruleForm.receiveAddress }}</p>
                            <el-button
                                plain
                                type="primary"
                                size="small"
                                @click="onClickChooseAddress(1)"
                                >选择地址</el-button
                            >
                        </div>
                    </el-form-item>
                </div>
            </div>
            <el-form-item
                v-if="!isEdit"
                label="预约时间"
                prop="reservationTimeRange"
            >
                <div class="flex">
                    <el-date-picker
                        v-model="state.ruleForm.date"
                        type="date"
                        placeholder="请选择日期"
                        value-format="YYYY-MM-DD"
                        class="mr-10 !w-150"
                        :disabled-date="disabledDate"
                        @change="validateTime"
                    />
                    <el-time-select
                        v-model="state.ruleForm.time"
                        start="08:00"
                        step="01:00"
                        end="19:00"
                        :min-time="state.minTimeSelect"
                        placeholder="请选择时间"
                        class="!w-180"
                        @change="validateTime"
                    />
                </div>
                <div
                    v-if="state.ruleForm.reservationTimeRange"
                    class="input-tips"
                >
                    预计上门时间：<code>{{
                        state.ruleForm.reservationTimeRange
                    }}</code>
                </div>
            </el-form-item>

            <!-- 货物信息 -->
            <el-form-item label="货物名称" prop="orderGoods.goodsName">
                <el-input
                    v-model.trim="state.ruleForm.orderGoods.goodsName"
                    clearable
                    placeholder="请输入货物名称"
                />
            </el-form-item>
            <el-form-item label="货物类型" prop="orderGoods.goodsTypeSid">
                <SelectLoadMore
                    v-model:selectValue="state.ruleForm.orderGoods.goodsTypeSid"
                    v-model:options="state.goodsTypeOptions"
                    v-model:needFilterOptions="state.needFilterGoodsTypeOptions"
                    value="sid"
                    label="goodsTypeName"
                    popperClass="goodsType"
                    placeholder="请选择货物类型"
                    :apiFun="getGoodsTypeOptions"
                />
            </el-form-item>
            <template v-if="!isEdit">
                <el-form-item label="线路" prop="lineSid">
                    <SelectLoadMore
                        v-model:selectValue="state.ruleForm.lineSid"
                        v-model:options="state.lineOptions"
                        value="sid"
                        label="lineName"
                        popperClass="line"
                        placeholder="请选择线路"
                        :apiFun="getLineOptions"
                        @change="onLineChange"
                    />
                </el-form-item>
                <!-- 线路配置 -->
                <el-form-item
                    v-if="state.ruleForm.lineSid"
                    label="线路配置"
                    prop="selectedConfigId"
                >
                    <el-table
                        v-if="state.lineConfigs?.length"
                        ref="configTableRef"
                        class="mb-10"
                        max-height="300"
                        :data="state.lineConfigs"
                        :header-cell-style="{
                            background: '#F5F7FA',
                            textAlign: 'center',
                        }"
                        :cell-style="{
                            textAlign: 'center',
                        }"
                        border
                        element-loading-background="rgba(255, 255, 255, 0.6)"
                        @select="onConfigSelect"
                    >
                        <el-table-column
                            type="selection"
                            width="55"
                            label-class-name="hide-checkbox"
                        />
                        <el-table-column
                            prop="preserveName"
                            label="保藏类型"
                            min-width="120"
                        >
                        </el-table-column>
                        <el-table-column
                            prop="vehicleName"
                            label="运输方式"
                            min-width="120"
                        >
                        </el-table-column>
                        <el-table-column
                            prop="pricingName"
                            label="计价方式"
                            min-width="300"
                        >
                            <template #default="{ row }">
                                <p v-if="row.pricingType === 1">
                                    {{ row.pricingName }}：{{
                                        fenToYuan(row.weightUnitPrice)
                                    }}元/kg
                                </p>
                                <div v-if="row.pricingType === 2">
                                    {{ row.pricingName }}：
                                    <p
                                        v-for="item in row.sizeSaveDTO"
                                        :key="item.sid"
                                    >
                                        {{ item.normsName }}：{{
                                            fenToYuan(item.unitPrice)
                                        }}元/个
                                    </p>
                                </div>
                            </template>
                        </el-table-column>
                        <el-table-column label="短运费" min-width="270">
                            <template #default="{ row }">
                                <!-- 无短运费 -->
                                <span v-if="row.shortType === 1">无</span>
                                <!-- 有短运费 -->
                                <template v-if="row.shortType === 0">
                                    <span v-if="row.pricingType === 1"
                                        >免费重量：{{
                                            row.shortWeightSaveDTO.freeWeight
                                        }}kg,超出单位价：{{
                                            fenToYuan(
                                                row.shortWeightSaveDTO.unitPrice
                                            )
                                        }}元/kg</span
                                    >
                                    <span v-if="row.pricingType === 2"
                                        >免费体积：{{
                                            row.shortSizeSaveDTO.freeSize
                                        }}m³,超出单位价：{{
                                            fenToYuan(
                                                row.shortSizeSaveDTO.unitPrice
                                            )
                                        }}元/m³</span
                                    >
                                </template>
                            </template>
                        </el-table-column>
                    </el-table>
                </el-form-item>
            </template>

            <template v-if="selectedConfig">
                <!-- 按重量 -->
                <template v-if="selectedConfig.pricingValue === 1">
                    <el-form-item
                        label="货物重量"
                        prop="orderGoods.goodsWeight"
                    >
                        <el-input-number
                            v-model="state.ruleForm.orderGoods.goodsWeight"
                            :min="0"
                            :precision="2"
                        />
                        <span class="ml-10">kg</span>
                    </el-form-item>
                </template>
                <!-- 按体积 -->
                <template v-if="selectedConfig.pricingValue === 2">
                    <el-form-item
                        label="装箱规格"
                        prop="orderGoods.goodsNormsSid"
                    >
                        <el-select
                            v-model="state.ruleForm.orderGoods.goodsNormsSid"
                            placeholder="请选择装箱规格"
                        >
                            <el-option
                                v-for="item in state.normOptions"
                                :key="item.sid"
                                :label="item.name"
                                :value="item.sid"
                            />
                        </el-select>
                    </el-form-item>
                    <el-form-item
                        label="规格数量"
                        prop="orderGoods.normsNumber"
                    >
                        <el-input-number
                            v-model="state.ruleForm.orderGoods.normsNumber"
                            :min="0"
                            :precision="0"
                        />
                    </el-form-item>
                </template>
            </template>

            <template v-if="!isEdit">
                <el-form-item label="优惠券" prop="couponSid">
                    <SelectLoadMore
                        v-model:selectValue="state.ruleForm.couponSid"
                        v-model:options="state.couponOptions"
                        value="sid"
                        label="couponName"
                        popperClass="coupon"
                        placeholder="请选择优惠券"
                        :apiFun="getCouponOptions"
                    />
                </el-form-item>
                <el-form-item label="状态" prop="status">
                    <el-radio-group v-model="state.ruleForm.status">
                        <el-radio
                            v-for="item in state.statusList"
                            :key="item.memberKey"
                            :value="item.memberKey"
                            >{{ item.memberName }}</el-radio
                        >
                    </el-radio-group>
                </el-form-item>
            </template>
        </el-form>

        <div class="foot-btn flexs-center mt-30">
            <h3 class="absolute left-20">
                预估费用：<span class="color-red-5"
                    >￥{{
                        state.estPrice === null
                            ? "--"
                            : fenToYuan(state.estPrice)
                    }}</span
                >
            </h3>
            <el-button
                type="primary"
                :loading="form_loading"
                @click="submitForm(ruleRef)"
            >
                {{ isEdit ? "修改" : "下单" }}
            </el-button>
        </div>

        <go-back />
    </div>

    <el-dialog v-model="state.showMap" title="选择地址" top="5vh">
        <TencentMap
            ref="mapRef"
            :marker-geometries="state.marker"
            :markerStyles="markerStyles"
            @clickMap="onClickMap"
            @chooseSearchRes="chooseSearchRes"
        >
            <template #search>
                <el-segmented
                    v-model="state.activeAddress"
                    :options="segmentedList"
                    block
                    class="ml-10"
                />
                <el-button
                    class="ml-auto"
                    type="primary"
                    @click="confirmChooseAddress"
                >
                    确定
                </el-button>
            </template>
        </TencentMap>
    </el-dialog>
</template>

<script setup>
import {
    inject,
    ref,
    onMounted,
    reactive,
    watch,
    nextTick,
    computed,
} from "vue";
import { useRouter, useRoute } from "vue-router";
import GoBack from "@components/GoBack.vue";
import SelectLoadMore from "@/components/selectLoadMore.vue";
import { getGoodsTypes } from "@/apis/enterprise/goodsType";
import { getUserCoupons } from "@/apis/user/user";
import {
    proxyCustomerPlaceOrder,
    editOrder,
    getOrderDetail,
    getOrderEstPrice,
} from "@/apis/order/order";
import {
    getLines,
    getLineConfigs as getLineConfigsApi,
} from "@/apis/enterprise/line";
import TencentMap from "@/components/TencentMap.vue";
import { fenToYuan } from "@/assets/common/utils.js";
import { useDictStore } from "@stores/dict.js";

const dictStore = useDictStore();
dictStore.getDictMembers("data_status").then((res) => (state.statusList = res));

const router = useRouter();
const route = useRoute();
const $message = inject("$message");

const sid = route.query.sid;
const isEdit = ref(false);
const form_loading = ref(false);
const ruleRef = ref(null);
const mapRef = ref(null);
const configTableRef = ref(null);
const segmentedList = [
    {
        value: 0,
        label: "寄",
    },
    {
        value: 1,
        label: "收",
    },
];
const state = reactive({
    statusList: [],
    ruleForm: {
        couponSid: null,
        ownerType: null,
        status: 0,
        lineSid: null,
        orderGoods: {
            goodsName: null,
            goodsNormsSid: null,
            goodsTypeSid: null,
            goodsWeight: null,
            normsNumber: null,
            pricingTypeSid: null,
        },
        preserveSid: null,
        receiveAddress: null,
        receiveDistrictCode: null,
        receiveLatitude: null,
        receiveLongitude: null,
        receiveName: null,
        receivePhone: null,
        reservationTimeRange: null,
        senderAddress: null,
        senderDistrictCode: null,
        senderLatitude: null,
        senderLongitude: null,
        senderName: null,
        senderPhone: null,
        userSid: null,
        vehicleSid: null,
        date: null,
        time: null,
        selectedConfigId: null, // 选中的线路配置id
    },
    rules: {
        selectedConfigId: [
            { required: true, message: "请选择线路配置", trigger: "blur" },
        ],
        senderName: [
            { required: true, message: "请输入寄件人姓名", trigger: "blur" },
        ],
        senderPhone: [
            { required: true, message: "请输入寄件人电话", trigger: "blur" },
        ],
        senderDistrictCode: [
            { required: true, message: "请选择寄件人地址", trigger: "blur" },
        ],
        receiveName: [
            { required: true, message: "请输入收件人姓名", trigger: "blur" },
        ],
        receivePhone: [
            { required: true, message: "请输入收件人电话", trigger: "blur" },
        ],
        receiveDistrictCode: [
            { required: true, message: "请选择收件人地址", trigger: "blur" },
        ],
        reservationTimeRange: [
            { required: true, message: "请选择预约时间", trigger: "blur" },
        ],
        lineSid: [{ required: true, message: "请选择线路", trigger: "blur" }],
        "orderGoods.goodsName": [
            { required: true, message: "请输入货物名称", trigger: "blur" },
        ],
        "orderGoods.goodsTypeSid": [
            { required: true, message: "请选择货物类型", trigger: "blur" },
        ],
        "orderGoods.goodsWeight": [
            { required: true, message: "请输入货物重量", trigger: "blur" },
        ],
        "orderGoods.goodsNormsSid": [
            { required: true, message: "请选择货物规格", trigger: "blur" },
        ],
        "orderGoods.normsNumber": [
            { required: true, message: "请输入规格数量", trigger: "blur" },
        ],
    },
    minTimeSelect: null,
    goodsTypeOptions: [],
    needFilterGoodsTypeOptions: [],
    pricingTypeOptions: [],
    normOptions: [],
    preserveOptions: [],
    vehicleOptions: [],
    lineOptions: [],
    lineConfigs: [], // 线路配置
    couponOptions: [],
    showMap: false,
    activeAddress: 0, // 0 寄件 1 收件
    senderLocation: null,
    receiveLocation: null,
    estPrice: null,
    marker: [],
});

// 选中的线路配置
const selectedConfig = computed(() => {
    return state.lineConfigs.find(
        (item) => item.id === state.ruleForm.selectedConfigId
    );
});

// 上门时间
watch(
    [() => state.ruleForm.date, () => state.ruleForm.time],
    ([date, time]) => {
        if (!date || !time) return (state.ruleForm.reservationTimeRange = null);

        const endTime = Number(time.split(":")[0]) + 1 + ":00";
        state.ruleForm.reservationTimeRange = `${date} ${time}-${endTime}`;
    }
);

// 绘制点标记
watch(
    [() => state.senderLocation, () => state.receiveLocation],
    ([sender, receive]) => {
        const geometries = [];
        if (sender) {
            geometries.push({
                position: sender,
                styleId: "sender",
                content: "寄",
            });
        }
        if (receive) {
            geometries.push({
                position: receive,
                styleId: "receive",
                content: "收",
            });
        }
        state.marker = geometries;
    },
    { deep: true }
);

// 计算预估价格
watch(
    [
        () => state.ruleForm.couponSid,
        () => state.ruleForm.lineSid,
        () => state.ruleForm.preserveSid,
        () => state.ruleForm.vehicleSid,
        () => state.ruleForm.orderGoods.pricingTypeSid,
        () => state.ruleForm.orderGoods.goodsNormsSid,
        () => state.ruleForm.orderGoods.goodsWeight,
        () => state.ruleForm.orderGoods.normsNumber,
    ],
    ([
        couponSid,
        lineSid,
        preserveSid,
        vehicleSid,
        pricingTypeSid,
        goodsNormsSid,
        goodsWeight,
        normsNumber,
    ]) => {
        if (lineSid && preserveSid && vehicleSid && pricingTypeSid) {
            if (selectedConfig.value) {
                switch (selectedConfig.value.pricingValue) {
                    case 1:
                        // 按重量
                        if (goodsWeight) getPrice();
                        break;
                    case 2:
                        // 按体积
                        if (goodsNormsSid && normsNumber) getPrice();
                        break;
                }
            }
        } else {
            state.estPrice = null;
        }
    }
);

onMounted(() => {
    if (/Edit$/.test(route.name)) {
        isEdit.value = true;
        getDetail();
    } else {
        state.ruleForm.ownerType = Number(route.query.ownerType);
    }
});

// 获取选中的线路配置
const getSelectedLineConfig = () => {
    // 计价方式为按体积时，获取装箱规格选项
    state.ruleForm.selectedConfigId = state.ruleForm.lineConfigId;

    const config = state.lineConfigs.find(
        (item) => item.id === state.ruleForm.selectedConfigId
    );
    if (config) {
        state.ruleForm.preserveSid = config.preserveSid;
        state.ruleForm.vehicleSid = config.vehicleSid;
        if (state.ruleForm.orderGoods.pricingType === 2) {
            state.normOptions = config.sizeSaveDTO.map((item) => {
                return {
                    sid: item.normsSid,
                    name: item.normsName,
                };
            });
        }
    }
};

const getLineOptions = async (params) => {
    const res = await getLines({
        ...params,
        lineName: params.keyword,
    });
    if (res.data.code == 200) {
        return res;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const onLineChange = (lineSid) => {
    lineSid && getLineConfigs();
};

const getLineConfigs = async () => {
    const res = await getLineConfigsApi({ sid: state.ruleForm.lineSid });
    if (res.data.code == 200) {
        state.lineConfigs = res.data.data;
        state.lineConfigs.forEach((item) => {
            const pricingType = item.pricingValue;
            item.pricingType = pricingType;

            if (pricingType === 1) {
                // 按重量
                if (item.shortType === 0) {
                    // 含短运费
                    item.shortWeightSaveDTO = {
                        freeWeight: item.freeWeight,
                        unitPrice: item.weightShortPrice,
                    };
                }
            }
            if (pricingType === 2) {
                // 按体积
                if (item.shortType === 0) {
                    // 含短运费
                    item.shortSizeSaveDTO = {
                        freeSize: item.freeSize,
                        unitPrice: item.sizeShortPrice,
                    };
                }
                // 装箱规格
                item.sizeSaveDTO = item.configSize.map(
                    ({ norms, sizeUnitPrice }) => {
                        return {
                            normsSid: norms.sid,
                            normsName: `${norms.normsName}(${norms.normsLength} * ${norms.normsWide} * ${norms.normsHigh})`,
                            unitPrice: sizeUnitPrice,
                        };
                    }
                );
            }
        });
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const onConfigSelect = (_, row) => {
    // 清空所有选中
    configTableRef.value.clearSelection();
    // 只选中当前行
    configTableRef.value.toggleRowSelection(row, true);
    state.ruleForm.selectedConfigId = row.id;
    // 保藏类型
    state.ruleForm.preserveSid = row.preserveSid;
    // 运输方式
    state.ruleForm.vehicleSid = row.vehicleSid;
    // 计价方式
    state.ruleForm.orderGoods.pricingTypeSid = row.pricingSid;
    // 计价方式按体积时
    if (row.pricingValue === 2) {
        // 添加装箱规格选项
        state.normOptions = row.sizeSaveDTO.map((item) => {
            return {
                sid: item.normsSid,
                name: item.normsName,
            };
        });
    }
};

const getCouponOptions = async (params) => {
    const res = await getUserCoupons({
        ...params,
        state: 1,
        userSid: sid,
        couponName: params.keyword,
    });
    if (res.data.code == 200) {
        return res;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getGoodsTypeOptions = async (params) => {
    const res = await getGoodsTypes({
        ...params,
        goodsTypeName: params.keyword,
    });
    if (res.data.code == 200) {
        return res;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getPrice = async () => {
    const res = await getOrderEstPrice({
        ...state.ruleForm,
        ...state.ruleForm.orderGoods,
    });
    if (res.data.code == 200) {
        state.estPrice = res.data.data;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getDetail = async () => {
    const res = await getOrderDetail({ sid });
    if (res.data.code == 200) {
        state.ruleForm = res.data.data;
        // 货物类型
        const goodsType = {
            sid: state.ruleForm.orderGoods.goodsTypeSid,
            goodsTypeName: state.ruleForm.orderGoods.goodsTypeName,
        };
        state.needFilterGoodsTypeOptions.push(goodsType);
        state.goodsTypeOptions.push(goodsType);

        if (state.ruleForm.senderDistrictCode) {
            state.senderLocation = new TMap.LatLng(
                state.ruleForm.senderLatitude,
                state.ruleForm.senderLongitude
            );
        }
        if (state.ruleForm.receiveDistrictCode) {
            state.receiveLocation = new TMap.LatLng(
                state.ruleForm.receiveLatitude,
                state.ruleForm.receiveLongitude
            );
        }

        await getLineConfigs();
        getSelectedLineConfig();
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const disabledDate = (time) => {
    return time.getTime() <= Date.now() - 1000 * 3600 * 24;
};

const validateTime = () => {
    if (Date.now() > new Date(state.ruleForm.date)) {
        // 今天
        let hour = new Date().getHours() - 1;
        hour = hour < 10 ? "0" + hour : hour;
        state.minTimeSelect = hour + ":00";
    } else {
        state.minTimeSelect = null;
    }
    nextTick(() => {
        if (state.ruleForm.reservationTimeRange)
            ruleRef.value.validateField("reservationTimeRange");
    });
};

// 点标记样式
const markerBaseStyle = {
    color: "#000",
    size: 25,
    direction: "top", // 文字位置
};
// 点标记样式
const markerStyles = {
    sender: new TMap.MarkerStyle(markerBaseStyle),
    receive: new TMap.MarkerStyle({
        ...markerBaseStyle,
        color: "#ef4444",
    }),
};

const onClickChooseAddress = (active) => {
    state.showMap = true;
    state.activeAddress = active;

    if (!mapRef.value) {
        nextTick(() => {
            mapRef.value.initMap();
        });
    }
};

const onClickMap = (e) => {
    state[["sender", "receive"][state.activeAddress] + "Location"] = e.latLng;
};

// 选择搜索地点
const chooseSearchRes = (e) => {
    state[["sender", "receive"][state.activeAddress] + "Location"] =
        e.location.location;
};

// 逆地址解析获取地址
const getAddress = async (key) => {
    const location = state[key + "Location"];
    if (!location) return;
    try {
        const geocoder = new TMap.service.Geocoder();
        const res = await geocoder.getAddress({ location });
        console.log(res);
        const {
            address_component: {
                province,
                city,
                district,
                street,
                street_number,
            },
            ad_info: { adcode },
            location: { lat, lng },
        } = res.result;
        // 行政区划编码
        state.ruleForm[key + "DistrictCode"] = adcode;
        // 地址
        state.ruleForm[key + "Address"] =
            province + city + district + street + street_number;
        // 经纬度
        state.ruleForm[key + "Latitude"] = lat;
        state.ruleForm[key + "Longitude"] = lng;
    } catch (error) {
        $message({ message: "获取地址失败", type: "error" });
    }
};

// 确认选择地址
const confirmChooseAddress = async () => {
    await Promise.all([getAddress("sender"), getAddress("receive")]);
    state.showMap = false;
};

// 提交表单
const submitForm = (formEl) => {
    if (!formEl) return;
    formEl.validate(async (valid, fields) => {
        if (valid) {
            form_loading.value = true;
            let res = null;
            if (isEdit.value) {
                res = await editOrder(state.ruleForm);
            } else {
                state.ruleForm.userSid = sid;
                res = await proxyCustomerPlaceOrder(state.ruleForm);
            }
            form_loading.value = false;
            if (res.data.code == 200) {
                $message({
                    message: isEdit.value ? "修改成功" : "下单成功",
                    type: "success",
                });
                router.back();
            } else {
                $message({ message: res.data.msg, type: "error" });
            }
        }
    });
};
</script>

<style lang="less" scoped>
:deep(.el-table__inner-wrapper:before) {
    height: 0;
}
:deep(.compass-img) {
    width: auto !important;
}

:deep(.hide-checkbox .cell .el-checkbox) {
    display: none;
}
</style>
